package cn.bonoon.kernel.web;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.persistence.EntityManager;

import org.springframework.context.ApplicationContext;

import cn.bonoon.kernel.bytecode.BytecodeFactory;
import cn.bonoon.kernel.bytecode.ConfigConverter;
import cn.bonoon.kernel.events.BaseEvent;

public final class ConfigManager {
	
	private final static ConfigManager manager = new ConfigManager();
	public static ConfigManager getManager() {
		return manager;
	}
	
	private final Map<Class<?>, ConfigConverter> configCached;
	private ConfigManager(){
		configCached = new ConcurrentHashMap<Class<?>, ConfigConverter>();
	}

	private ConfigConverter __converter(ApplicationContext applicationContext, Class<?> configClass) throws Exception{
		ConfigConverter cc = configCached.get(configClass);
		if(null == cc){
			cc = BytecodeFactory.config(applicationContext, configClass);
			configCached.put(configClass, cc);
		}
		return cc;
	}

	public Object read(ApplicationContext applicationContext, EntityManager entityManager, BaseEvent event) throws Exception {
		Object configObject = event.getSource();
		if(null == configObject) return null;
		return read(applicationContext, entityManager, event, configObject.getClass());
	}

	public Object read(ApplicationContext applicationContext, EntityManager entityManager, Object configObject) throws Exception {
		if(null == configObject) return null;
		return read(applicationContext, entityManager, new BaseEvent(configObject), configObject.getClass());
	}

	public Object read(ApplicationContext applicationContext, EntityManager entityManager, BaseEvent event, Class<?> configClass) throws Exception{
		return __converter(applicationContext, configClass).get(entityManager, event);
	}

	public void write(ApplicationContext applicationContext, EntityManager entityManager, BaseEvent event) throws Exception{
		Object configObject = event.getSource();
		if(null != configObject){
			__converter(applicationContext, configObject.getClass()).set(entityManager, event);
		}
	}
}
